home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: napsaprefs.c,v 3.9 1994/05/18 15:09:54 ppessi Exp ppessi $";
- /*
- * napsaprefs.c --- preferences for napsaterm
- *
- * Author: ppessi <Pekka.Pessi@hut.fi>
- *
- * Copyright (c) 1993 Pekka Pessi
- *
- * Created : Sun Nov 7 08:27:25 1993 ppessi
- * Last modified: Wed May 18 18:08:55 1994 ppessi
- *
- * $Log: napsaprefs.c,v $
- * Revision 3.9 1994/05/18 15:09:54 ppessi
- * Changed default ctrl8bit tool type to ctrl8bit=no
- *
- * Revision 3.8 1994/05/14 12:49:00 ppessi
- * Multicharacter options are now preceded with double hyphen.
- * Added "Control Codes" (7/8 bit) entry into "Setup" menu.
- *
- * Revision 3.7 1994/05/11 12:53:42 ppessi
- * Merged changes from Napsaterm 3.5 by R. Knop
- *
- * Revision 3.6 1994/02/25 16:08:03 ppessi
- * Fixed a bug in the national setting (only Danish and US could be selected)
- *
- * Revision 3.5 1994/02/25 02:33:38 ppessi
- * Added RCS ID
- *
- * Revision 3.4 1994/02/25 02:00:48 ppessi
- * Reverted back to S:Napsaprefs preference file
- *
- * Revision 3.3 1994/01/16 18:21:15 ppessi
- * No perrorparse() printouts
- *
- * Revision 3.2 94/01/08 08:54:52 ppessi
- * Enabled switch tool types; added support to different program names
- *
- * Revision 3.1 94/01/07 22:51:25 ppessi
- * Version 3 beta
- *
- * Revision 2.1 93/11/18 18:34:12 ppessi
- * Changed menu format.
- *
- * Revision 2.0 93/11/15 03:38:53 ppessi
- * Version 2 initial revision
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "nifty.h"
- #include "amiga.h"
- #include "napsaprefs.h"
- #include "display.h"
- #include "dispmacros.h"
- #include "wimp.h"
-
- #include <workbench/workbench.h>
- #include <workbench/startup.h>
-
- #if USE_PRAGMAS
- #include <proto/icon.h>
- #endif
- #if USE_INLINE
- #include <inline/icon.h>
- #endif
- #if USE_CLIB
- #include <clib/icon_protos.h>
- #endif
-
- #define PREFSFILE \
- "AmiTCP:db/NapsaPrefs" NUL "s:NapsaPrefs" NUL "s:NiftyPrefs" NUL
-
- /*
- * Hosts to connect
- */
- #define MAXHOSTS 63 /* you can specify only 63 hosts */
- int hostc;
- char *hostarray[MAXHOSTS + 1];
-
- static void addhost(char *newhost, void *dummy);
-
- struct napsaprefs np;
-
- struct parsing {
- char p_type;
- char p_slen; /* significant length */
- ushort p_offset;
- union {
- const char *pu_option;
- const char *pu_values;
- int (*pu_func)(char *, void *);
- } p;
- char *p_resource;
- long p_default;
- };
-
- #define p_option p.pu_option
- #define p_values p.pu_values
- #define p_func p.pu_func
-
- #define T_END 0
- #define T_STRING 1
- #define T_FLAG 2 /* true/false */
- #define T_TOGGLE 3 /* option will toggle the default */
- #define T_NUMBER 4
- #define T_SPECIAL 5
- #define T_ENUM 6
-
- #define OFFSET_OF(x) ((ushort)&((struct napsaprefs *)NULL)->x)
-
- #define LPARSE(type, what, optnam, resource, default) \
- {type,2,OFFSET_OF(what),optnam,resource,(long)default}
-
- #define PARSE(type, what, optnam, resource, default) \
- {type,sizeof(optnam)-1,OFFSET_OF(what),optnam,resource,(long)default}
-
- #define PENUM(what, resource, values, default, len) \
- {T_ENUM,len,OFFSET_OF(what),values,resource,(long)default}
-
- #define PRESET(type, what, resource, default) \
- {type,0,OFFSET_OF(what),NULL,resource,(long)default}
-
- #define PSPECIAL(what, resource, function) \
- {T_SPECIAL, 0, OFFSET_OF(what), (void *)function, resource, 0}
-
- #define NP_ADDR(offset) (void*)((char*)&np + offset)
-
- extern char nation_names[];
-
- static char national_names[] =
- "None" NUL "Multinational" NUL "National" NUL;
-
- static char bell_names[] =
- "None" NUL "Visual" NUL "Audio" NUL "Both" NUL "Display" NUL;
-
- static char cursor_names[] =
- "Underlined" NUL "Block" NUL "Invisible" NUL;
-
- static char sizing_names[] =
- "None" NUL "Column" NUL "Row" NUL;
-
- static char emulation_names[] =
- "vt102" NUL "vt52" NUL "h19" NUL;
-
- static char mouse_names[] =
- "Off" NUL "Down" NUL "Up" NUL "Both" NUL;
-
- /* Added RKNOP 940328 */
- static char keypad_names[] =
- "Numeric" NUL "Application" NUL;
- /* End added RKNOP */
-
- static const struct parsing presets[] =
- {
- PARSE(T_STRING, logname, "l", NULL, NULL),
- PARSE(T_FLAG, show_version, "V", NULL, 1),
- PARSE(T_TOGGLE, wait_to_end, "w", "WAITTOEND", 0),
-
- /* emulation mode */
- PENUM(emulation, "EMULATION", emulation_names, EMU_VT102, 3),
- PARSE(T_FLAG, emulation, "-vt102", NULL, EMU_VT102),
- PARSE(T_FLAG, emulation, "-vt52", NULL, EMU_VT52),
- PARSE(T_FLAG, emulation, "-h19", NULL, EMU_H19),
-
- PENUM(national, "NATIONAL", national_names, 0, 2),
- /* Default is US (plain ASCII) */
- PENUM(nation, "NATION", nation_names, 0, 2),
- PSPECIAL(keymap, "KEYMAP", parsekeymap),
- PSPECIAL(keymap, "KEYBOARD", parsekeymap),
- #if 0
- PRESET(T_STRING, nation, "NATION", NULL),
- PRESET(T_STRING, keymap, "KEYMAP", NULL),
- PRESET(T_STRING, keymap, "KEYBOARD", NULL),
- #endif
-
- LPARSE(T_TOGGLE, slow, "-slow", NULL, 0),
-
- /*Added RKNOP 940328*/
- /* Keypad mode */
- PENUM(applkeypad, "KEYPAD", keypad_names, KEYP_NUMERIC, 2),
- PARSE(T_FLAG, applkeypad, "-numeric", NULL, KEYP_NUMERIC),
- PARSE(T_FLAG, applkeypad, "-application", NULL, KEYP_APPL),
- /*end added RKNOP 940328*/
-
- /* Cursor style, see "dispmacros.h" */
- PENUM(visual, "CURSOR", cursor_names, CUR_BLOCK, 1),
- PARSE(T_FLAG, visual, "-ic", NULL, 2),
-
- /* stripping */
- PARSE(T_TOGGLE, pass8, "7", "PASS8", 1),
- PRESET(T_FLAG, altismeta, "ALTISMETA", 0),
- PARSE(T_TOGGLE, invert, "v", "INVERSE", 0),
-
- PENUM(mouse, "MOUSE", mouse_names, 0, 0),
- PRESET(T_FLAG, backspace, "BACKSPACE2DELETE", 0),
- PRESET(T_FLAG, delete, "DELETE2BACKSPACE", 0),
- PRESET(T_FLAG, ctrl8bit, "CTRL8BIT", 0),
- PRESET(T_FLAG, blink, "CURSORBLINK", 0),
-
- PARSE(T_STRING, device, "d", "DEVICE", "serial.device"),
- PARSE(T_NUMBER, unit, "u", "UNIT", 0),
- PARSE(T_NUMBER, dnetwork, "N", NULL, 0),
- PARSE(T_NUMBER, bps, "B", "LINESPEED", 38400),
- LPARSE(T_FLAG, shared, "-shared", NULL, 1),
- LPARSE(T_FLAG, stdio, "-stdio", NULL, 1),
- /* The telnet server port */
- PARSE(T_STRING, service, "s", "SERVICE", "telnet"),
- /* LPARSE(T_FLAG, telnet, "telnet", NULL, 1), */
-
- /* This won't change the prefs structure */
- PSPECIAL(emulation, "HOST", addhost),
- PARSE(T_STRING, remotename, "r", "REMOTENAME", NULL),
- PRESET(T_STRING, remoteterm, "REMOTETYPE", NULL),
-
- /* bell type */
- PENUM(bell_type, "BELL", bell_names, BELL_VISUAL, 1),
-
- PARSE(T_TOGGLE, col80, "-80", "FIXEDCOLUMNS", 0),
-
- /* sizing gadget */
- PENUM(size_gadget, "SIZEGADGET", sizing_names, SIZE_COLUMN, 1),
- PARSE(T_STRING, title, "p", "TITLE", NULL),
- PARSE(T_STRING, geometry, "g", "GEOMETRY", NULL),
- PARSE(T_STRING, pubscname,"S", "PUBSCREENNAME", NULL),
- PARSE(T_STRING, basefont, "f", "BASEFONT", DEFAULTFONTDEF),
-
- {T_END}
- };
-
- /*
- * show options
- */
- static void usage(void)
- {
- /* puts(version); */
- /* puts(copyright); */
- PutStr("Usage: " PROGNAME " [-option ...]\n"
- "Available " PROGNAME " options are:\n"
- " -V show version number & copyright notice\n"
- " --h19 emulate an h19 instead of a vt102 terminal\n"
- " --vt52 emulate a vt52 on startup\n"
- " --vt102 emulate a vt102 on startup (default emulation)\n"
- " -l <file> write all output to a log file\n"
- " --slow start up in slow mode\n"
- " --ic start up with invisible cursor\n"
- " --numeric use numeric keypad\n"
- " --application use application keypad\n"
- " -w wait after program ends before closing window\n"
- " -d <devicename> specify device to use (e.g. serial.device)\n"
- " -u <unit #> specify unit number to use (see -d)\n"
- " -B <linespeed> specify line speed to use\n"
- " --shared open device in shared mode\n"
- " --stdio take input from stardard input.\n"
- " -N <net> specify DNet network number\n"
- " -s <service> specify TCP service name\n"
- " -r <username> specify remote user name to use\n"
- " -7 strip 8th bit of character codes\n"
- " -S <screen> specify public screen name\n"
- " --80 set to fixed 80 columns\n"
- " -f <font>/<size> set the name and size of the default font\n"
- " -p <name> set the program name\n"
- " -g <l>/<t>/<w>/<h> set up window geometry.");
- exit(1);
- }
-
- /*
- * Set default values
- */
- static void preset(void)
- {
- const struct parsing *p;
-
- hostc = 0;
-
- for (p = presets; p->p_type != T_END; p++) {
- if (p->p_resource) {
- void *what = NP_ADDR(p->p_offset);
- switch (p->p_type) {
- case T_STRING:
- case T_NUMBER:
- *(long*)what = p->p_default;
- break;
- case T_FLAG:
- case T_TOGGLE:
- case T_ENUM:
- *(char*)what = p->p_default;
- break;
- }
- }
- }
- }
-
- /*
- * `secure' strdup that removes the LF
- */
- static char *pstrdup(char *s)
- {
- char *val;
- int size = 0;
-
- while (s[size] && s[size] != '\n')
- size++;
-
- val = malloc(size + 1);
- if (!val) {
- fatalError(MEMORY_ERROR_MSG);
- }
- memcpy(val, s, size);
- val[size] = '\0';
-
- return val;
- }
-
- /*
- * Add a new host to hosts structure
- */
- static void addhost(char *newhost, void *dummy)
- {
- if (hostc < MAXHOSTS) {
- hostarray[hostc++] = newhost;
- while (*newhost) {
- if (*newhost++ == '|') {
- newhost[-1] = '\0';
- if (hostc < MAXHOSTS) {
- hostarray[hostc++] = newhost;
- } else {
- break;
- }
- }
- }
- } else {
- free(newhost);
- }
- }
-
- /*
- * Parse a preset entry from icon or from preset file
- */
- static void parse_entry(const char *preset, char *value)
- {
- const struct parsing *p;
-
- for (p = presets; p->p_type != T_END; p++) {
- if (p->p_resource == NULL || strcmp(p->p_resource, preset))
- continue;
- switch (p->p_type) {
-
- case T_STRING:
- *(char**)NP_ADDR(p->p_offset) = pstrdup(value);
- break;
-
- case T_NUMBER:
- if (StrToLong(value, (long*)NP_ADDR(p->p_offset)) <= 0) {
- perrorparse("Expected number for option %s", p->p_resource);
- }
- break;
-
- case T_FLAG:
- case T_TOGGLE:
- if (*value == '0' ||
- *value == 'n' ||
- (*value == 'o' && value[1] == 'f') ||
- *value == 'f')
- *(char*)NP_ADDR(p->p_offset) = 0;
- else
- if (*value == '\0' ||
- *value == '1' ||
- *value == 'y' ||
- (*value == 'o' && value[1] == 'n') ||
- *value == 't')
- *(char*)NP_ADDR(p->p_offset) = 1;
- break;
-
- case T_SPECIAL:
- /* Call the special function */
- p->p_func(pstrdup(value), NP_ADDR(p->p_offset));
- break;
-
- case T_ENUM:
- {
- /*
- * Find which token is given
- */
- int e;
- const char *t = p->p_values;
- char *n = value;
-
- /* NUL-terminate */
- while (*n && *n != '\n')
- n++;
- *n = '\0';
-
- for (e = 0; *t; e++) {
- if (p->p_slen ?
- !Strnicmp(t, value, p->p_slen) :
- !Stricmp(t, value)) {
- /* Found */
- *(char*)NP_ADDR(p->p_offset) = e;
- break;
- }
- while (*t++)
- ;
- }
- if (!*t)
- perrorparse("Illegal value %s for option %s", value, p->p_resource);
- }
- break;
- }
- break; /* for () */
- }
- if (p->p_type == T_END) {
- perrorparse("Unknown option %s", preset);
- }
- }
-
- /*
- * Parse preset file
- */
- static void parsepreset(char *myname, char *filename)
- {
- char *s, *preset, buf[256];
- BPTR fh;
-
- while (*filename) {
- if (fh = Open(filename, MODE_OLDFILE))
- break;
- filename += strlen(filename) + 1;
- }
- if (!*filename)
- return;
-
- buf[255] = '\0';
-
- while (FGets(fh, buf, sizeof(buf)-1)) {
- /* Comment? */
- if (!isalnum(buf[0]))
- continue;
- for (preset = s = buf; *s; s++) {
- if (*s == ':')
- break;
- else if (islower(*s))
- *s += 'A' - 'a';
- else if (*s == '.') {
- preset = s + 1;
- /* Is the program name correct? */
- if (strncmp(myname, buf, s - buf))
- goto not_for_me;
- }
- }
- if (*s) {
- *s++ = '\0';
- while (isspace(*s))
- s++;
- parse_entry(preset, s);
- }
- not_for_me:
- ;
- }
-
- Close(fh);
- return;
- }
-
- char **parseargs(char **argv)
- {
- char *cont;
- const struct parsing *p;
- char progname[128];
-
- strncpy(progname, FilePart(argv[0]), sizeof(progname));
- for (cont = progname; *cont; cont++) {
- if (islower(*cont))
- *cont += 'A' - 'a';
- }
-
- preset();
- parsepreset(progname, PREFSFILE);
-
- for (argv = argv + 1; *argv != NULL; argv++) {
- if (**argv == '-') {
- /* '-' ends options */
- if ((*argv)[1] == '\0')
- return argv + 1;
- cont = *argv + 1;
- for (p = presets; p->p_type != T_END; p++) {
- if (p->p_type < T_SPECIAL &&
- p->p_option &&
- !strncmp(p->p_option, cont, p->p_slen)) {
- void *what = NP_ADDR(p->p_offset);
- switch (p->p_type) {
- case T_STRING:
- case T_NUMBER:
- cont = *++cont ? cont : *(++argv);
- if (!cont) usage();
- if (p->p_type == T_NUMBER)
- StrToLong(cont, (long *)what);
- else
- *(char **)what = cont;
- break;
- case T_FLAG:
- *(char *)what = p->p_default;
- break;
- case T_TOGGLE:
- *(char *)what = !p->p_default;
- break;
- }
- break;
- }
- }
- /* Didn't found the option? */
- if (p->p_type == T_END) usage();
- } else {
- break;
- }
- }
-
- return argv;
- }
-
- /*
- * Workbench setup
- */
- static void parseicon(UBYTE *name)
- {
- struct DiskObject *dobj;
- char **toolarray;
- char *s, buf[256];
-
- if (!name)
- return;
-
- if (dobj = GetDiskObjectNew(name)) {
- for (toolarray = (char **)dobj->do_ToolTypes;
- toolarray && *toolarray;
- toolarray++) {
- s = strncpy(buf, *toolarray, sizeof(buf));
- buf[sizeof(buf) - 1] = '\0';
- while (*s && *s != '=')
- s++;
- if (*s)
- *s++ = '\0';
- parse_entry(buf, s);
- }
-
- /* Free the diskobject we got */
- FreeDiskObject(dobj);
- } else {
- addhost(pstrdup(name), NULL);
- }
- }
-
- char **parsewbargs(struct WBStartup *argmsg)
- {
- LONG i;
- struct WBArg *wb_arg_list = argmsg->sm_ArgList;
-
- preset();
-
- for (i = 0; i < argmsg->sm_NumArgs; i++, wb_arg_list++) {
- if (wb_arg_list->wa_Lock) {
- /* change to the proper directory */
- BPTR olddir = CurrentDir(wb_arg_list->wa_Lock) ;
-
- /* process the file */
- parseicon(wb_arg_list->wa_Name);
- /* change back to the original directory when done */
- CurrentDir(olddir) ;
- } else {
- /* something that does not support locks */
- parseicon(wb_arg_list->wa_Name);
- }
- }
-
- hostarray[hostc] = NULL;
-
- return hostarray;
- }
-
- #include <stdarg.h>
-
- #if 0
- /*
- * Print parse error
- */
- void perrorparse(char *fmt, ...)
- {
- va_list va;
-
- va_start(va, fmt);
- vfprintf(stderr,fmt, va);
- va_end(va);
- fputc('\n', stderr);
- }
- #else
- void perrorparse(char *fmt, ...)
- {
- }
- #endif
-
- /*
- * Setup menu items show their current value
- */
- #define SETUP_ITEMS 15
-
- struct setup_menu_item setup_items[SETUP_ITEMS + 1] =
- {
- {
- OFFSET_OF(national), 3,
- "National Mode",
- national_names,
- change_national
- },
- {
- OFFSET_OF(nation), 8,
- "Nation",
- nation_names,
- change_nation
- },
- {
- OFFSET_OF(emulation), 3,
- "Terminal Type",
- emulation_names,
- NULL
- },
- {
- OFFSET_OF(ctrl8bit), 2,
- "Control Codes",
- "7 bit" NUL "8 bit" NUL,
- NULL
- },
- {
- OFFSET_OF(backspace), 2,
- "Backspace is sent as",
- "Backspace" NUL "Delete" NUL,
- NULL
- },
- {
- OFFSET_OF(delete), 2,
- "Del is sent as",
- "Delete" NUL "Backspace" NUL,
- NULL
- },
- {
- OFFSET_OF(altismeta), 2,
- "Left Alt key is ",
- "Alt" NUL "Meta" NUL,
- NULL
- },
- {
- /* Added RKNOP 940328 */
- OFFSET_OF(applkeypad), 2,
- "Keypad",
- "Numeric" NUL "Application" NUL,
- NULL
- },
- {
- OFFSET_OF(mouse), 4,
- "Mouse Events",
- mouse_names,
- NULL
- },
- {
- OFFSET_OF(visual), 3,
- "Cursor",
- cursor_names,
- change_cursor
- },
- {
- OFFSET_OF(col80), 2,
- "Display Width",
- "Variable" NUL "80 Columns" NUL,
- change_mode80
- },
- {
- OFFSET_OF(slow), 2,
- "Display Speed",
- "Fast" NUL "Slow" NUL,
- NULL
- },
- {
- OFFSET_OF(bell_type), 5,
- "Bell Type",
- bell_names,
- NULL
- },
- {
- OFFSET_OF(invert), 2,
- "Reverse",
- NULL,
- change_invert
- },
- /* added RKNOP 940328 */
- {
- OFFSET_OF(ansi_LNM), 2,
- "ansi_LNM",
- NULL,
- change_ansi_LNM
- },
- /* end added RKNOP 940328 */
- { 0 }
- };
-
- int getsetup(unsigned int n)
- {
- return ((UBYTE*)&np)[setup_items[n].offset];
- }
-
- /*
- * Change setup menu item n, return new value
- *
- * If new value is illegal, won't call toggle function
- */
- int changesetup(unsigned int n, int val)
- {
- UBYTE *vp = ((UBYTE*)&np) + setup_items[n].offset;
-
- if (n >= SETUP_ITEMS)
- return -1;
-
- if (val >= 0 && val < setup_items[n].choices && *vp != val) {
- *vp = val;
- if (setup_items[n].change_f)
- setup_items[n].change_f(val);
- }
-
- return *vp;
- }
-
- #if 0
- int
- main(int argc, char **argv)
- {
- char **argv2 = parseargs(argv + 1);
-
- printpresets();
-
- if (*argv2) {
- puts(*argv2);
- }
-
- return 0;
- }
- #endif
-